// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import {ISwapManager} from "./interfaces/ISwapManager.sol";
import {FakeDex} from "./tests/FakeDex.sol";

abstract contract SwapManager is ISwapManager, ReentrancyGuard {
    using SafeERC20 for IERC20;

    function isAssetAllowed(address asset) public view virtual override returns (bool);
    function isDexAllowed(address dex) public view virtual override returns (bool);

    constructor() {}

    function swap(
        address dex,
        address tokenIn,
        address tokenOut,
        uint256 amountIn,
        uint256 amountOutMin
    ) public override onlyProtocolTrader {
        require(isDexAllowed(dex), "SwapManager: swap: dex is not allowed");
        require(isAssetAllowed(tokenIn), "SwapManager: swap: tokenIn is not allowed");
        require(isAssetAllowed(tokenOut), "SwapManager: swap: tokenOut is not allowed");
        IERC20(tokenIn).safeApprove(dex, amountIn);
        FakeDex(dex).swap(tokenIn, tokenOut, amountIn, amountOutMin);
    }

    modifier onlyProtocolTrader() virtual;
}
